//主要作用是实现大文件读取的分割
//可以分段读取
let fs = require('fs');
const path = require('path');
const resolve = (filename) => {
  return path.resolve(__dirname, filename);
};
//返回的是可读流对象
/*let rs = fs.createReadStream(resolve('a.txt'));
console.log('rs:',rs);*/
/*
rs: ReadStream {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 65536,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     paused: true,
     emitClose: false,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  _events: [Object: null prototype] { end: [Function] },
  _eventsCount: 1,
  _maxListeners: undefined,
  path: 'D:\\x\\node_tutorial\\11stream\\a.txt',
  fd: null,
  flags: 'r',
  mode: 438,
  start: undefined,
  end: Infinity,
  autoClose: true,
  pos: undefined,
  bytesRead: 0,
  closed: false }
*/

//基于fs.open、fs.read、fs.close
//调用fs.createReadStream，源码中就是 return new ReadStream
const ReadStream = require('./ReadStream');
// let rs = new ReadStream(resolve('a.txt'),{
let rs = fs.createReadStream(resolve('a.txt'),{
  flags:'r'
  // , encoding: null // 默认值: null，读取到的结果都是buffer类型，也可以给utf8
  // , encoding: 'utf8' //encoding 可以是 Buffer 接受的任何一种字符编码。
  /*
    如果指定了 fd，则 ReadStream 将会忽略 path 参数并将会使用指定的文件描述符。 这意味着将不会触发 'open' 事件。 fd 必须是阻塞的，非阻塞的 fd 应该传给 net.Socket。
    如果 fd 指向仅支持阻塞读取的字符设备（例如键盘或声卡），则在数据可用之前，读取操作不会完成。 这可以防止进程退出并且流自然地关闭。
  */
  // , fd:3
  // , mode:0o666 //默认值: 0o666  权限
  /*
    默认情况下，流在销毁后将不会触发 'close' 事件。 这与其他 Readable 流的默认行为相反。 将 emitClose 选项设置为 true 可更改此行为。
    如果 autoClose 为 false，则即使出现错误，文件描述符也不会被关闭。 应用程序负责关闭它并确保没有文件描述符泄漏。 如果 autoClose 设为 true（默认的行为），则在 'error' 或 'end' 事件时文件描述符将会被自动地关闭。
  */
  , autoClose:true
  , start:2 //开始位置
  , end:6 //结束位置 包前又包后
  , highWaterMark: 3 //默认为64k //也是分块读取所占用的恒定的内存，不管文件多大，只会占用这么多内存（它是一个中介 ），解决了大文件读取
}); //45 67 89 0

//拿到的是一个对象
// console.log('rs:',rs);

//默认叫非流动模式
let bufferArr = [];
rs.on('open', function (fd) {
  console.log(fd);
});
rs.on('error', function (err) {
  console.log(err);
});
rs.on('data', function (data) {
  console.log('data:', data); //data: <Buffer 31 32 33 34 35 36 37 38 39 30>
  console.log('data.toString:', data.toString()); //data: <Buffer 31 32 33 34 35 36 37 38 39 30>
  bufferArr.push(data);
  rs.pause(); //TODO 能够暂停 读取(这样就切换到了暂停模式)
  setTimeout(() => {
    rs.resume()
  }, 1000);
});
rs.on('end', function () {
  // console.log('Buffer.concat(bufferArr).toString():',Buffer.concat(bufferArr).toString()); //concat的参数必须是一个以buffer成员组成的数组
});
rs.on('close', function () { //close只有在文件正确打开后获得文件描述符后 关闭文件才会触发close
  console.log('close');
});

//close/open 这个两个事件是针对文件才有的 其它流里是没有的

/*
TODO 1 new的时候立马就会打开文件
TODO 2 on data的时立刻会切换为流动模式并调用read()
*/
